﻿using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using BSF.DistributedLock;
using BSF.DistributedLock.RedisLock;
using BSF.DistributedLock.SystemRuntime;
using BSF.Enums;
using BSF.Extensions;
using BSF.Log;
using BSF.ServicesResult;

namespace HuntingFishGame.CustomerApi
{
    /// <summary>
    /// 分布式锁扩展类
    /// </summary>
    public class DistributedLockHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="info"></param>
        /// <param name="controller"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static HttpResponseMessage TryLock2(BaseDistributedLockInfo info, ApiController controller, Func<object> action)
        {
            //var json = new JsonResult();
            //json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            try
            {
                if (info is RedisDistributedLockInfo)
                {
                    var redisinfo = info as RedisDistributedLockInfo;
                    if (string.IsNullOrEmpty(DistributedLockConfig.DistributedLockRedisServers))
                    {
                        throw new DistributedLockException("请在web.config或app.config中配置DistributedLockRedisServers");
                    }
                    //redis负载均衡
                    var redisserver = new RedisLoadBalance(DistributedLockConfig.GetDistributedLockRedisServerList()).ChooseRedisServer(info.DistributedLockKey);

                    using (var @lock = new RedisDistributedLockFromJava(redisserver, info.DistributedLockKey))
                    {
                        var islock = @lock.TryGetDistributedLock(info.GetLockTimeOut, info.TaskRunTimeOut);
                        if (islock == LockResult.Success)
                        {
                            var r = action.Invoke();

                            //手动释放锁资源 shenxf
                            @lock.Dispose();
                            if (r.GetType() == typeof(HttpResponseMessage)) //如果是列表类型的，需要记录总记录数和列表集合
                            {
                                return (HttpResponseMessage)r;
                            }
                            else
                            {
                                var result = new ApiResult(BSFAPICode.NormalError, "报名太火爆了，请稍后重试！");
                                return controller.Request.CreateResponse(HttpStatusCode.OK, result);
                            }
                        }
                        //分布式锁的服务出现异常了，不能提供服务了
                        else if (islock == LockResult.LockSystemExceptionFailure)
                        {
                            var result = new ApiResult(BSFAPICode.NormalError, "分布式锁配置异常！");
                            return controller.Request.CreateResponse(HttpStatusCode.OK, result);
                            //action();
                        }
                        //分布式锁获取超时了,备注:在获取锁的时间内,当前任务的锁未释放
                        else if (islock == LockResult.GetLockTimeOutFailure)
                        {
                            var result = new ApiResult(BSFAPICode.NormalError, "报名太火爆了，请稍后重试！！！");
                            return controller.Request.CreateResponse(HttpStatusCode.OK, result);
                        }

                        //return islock;
                    }

                }
                throw new DistributedLockException("info 参数传入错误");
            }
            catch (Exception exp)
            {
                ErrorLog.Write(string.Format("分布式尝试锁错误,key:{0}", (info == null ? "" : info.DistributedLockKey.NullToEmpty())), exp);
                throw exp;
            }
        }

    }
}
